package br.ufs.dcomp.lsp;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;

public class Pack {

	protected enum MessageType {
		CONNECT, DATA, ACK
	}

	static final int MESSAGESIZE = 100;
	protected MessageType type;
	protected short connId;
	protected short sequenceNumber;
	protected byte[] payload;
	protected InetAddress host;
	protected int port;

	public Pack(short connId, short sn, byte[] payload) {
		this(MessageType.DATA, connId, sn, payload, null, 0);
	}
	
	public Pack(short connId, short sn, byte[] payload, String host, int port) {
		this(MessageType.DATA, connId, sn, payload, host, port);
	}

	public static Pack getConnectPack() {
		return new Pack(MessageType.CONNECT, (short) 0, (short) 0, null, null, 0);
	}
	
	public static Pack getConnectPack(String host, int port) {
		return new Pack(MessageType.CONNECT, (short) 0, (short) 0, null, host, port);
	}

	public static Pack getAcknowledgementPack(short connId, short sn) {
		return new Pack(MessageType.ACK, connId, sn, null, null, 0);
	}
	
	public static Pack getAcknowledgementPack(short connId, short sn, String host, int port) {
		return new Pack(MessageType.ACK, connId, sn, null, host, port);
	}

	protected Pack(MessageType type, short connId, short sn, byte[] payload,
			String host, int port) {
		this.type = type;
		this.connId = connId;
		this.sequenceNumber = sn;
		this.payload = payload;
		try {
			if (host != null) {
				this.host = Inet4Address.getByName(host);
				this.port = port;
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}

	public short getConnId() {
		return connId;
	}

	public void setConnId(short connId) {
		this.connId = connId;
	}

	public short getSequenceNumber() {
		return this.sequenceNumber;
	}

	public void setSequenceNumber(short sn) {
		this.sequenceNumber = sn;
	}

	public byte[] getPayload() {
		return payload;
	}

	public void setPayload(byte[] payload) {
		this.payload = payload;
	}
	
	public InetAddress getHost() {
		return host;
	}

	public void setHost(String host) {
		try {
			this.host = Inet4Address.getByName(host);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		};
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	/**
	 * Encapsula as informacoes do pacote em um array de bytes para ser enviado
	 * no datagram.
	 * 
	 * @return Array de bytes para ser enviado.
	 */
	public byte[] toBytes() {
		ByteBuffer data = ByteBuffer.allocate(MESSAGESIZE);
		data.putShort((short) this.type.ordinal());
		data.putShort((short) this.connId);
		data.putShort((short) this.sequenceNumber);
		if (type == MessageType.DATA)
			data.put(payload);
		data.flip();
		return data.array();
	}
}
